/*
 * Created on 2005-10-19
 */
package com.jycrm.presentation.components.tab;
import java.io.IOException;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.tapestry.ApplicationRuntimeException;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.IPage;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.engine.AbstractService;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.IEngineServiceView;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.request.RequestContext;
import org.apache.tapestry.request.ResponseOutputStream;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

import com.jycrm.presentation.components.xmlservice.IXMLService;



/**
 * @author given
 * 2005-11-02
 */
public class TabService extends AbstractService implements IEngineService{ 
	public static final String SERVICE_NAME = "TabService";
	public static final String SERVICE = "service";
	public static final String COMPONENT = "component";
	public static final String CONTAINER = "container";

	public String getName(){
		return SERVICE_NAME;
	}
	
	public ILink getLink(IRequestCycle cycle, IComponent component,	Object[] parameters){
		throw new UnsupportedOperationException();
    }
    
	public void service(IEngineServiceView engine, IRequestCycle cycle, ResponseOutputStream output)
			throws IOException{
		RequestContext context = cycle.getRequestContext();
		String[] contextParams = getServiceContext(context);
		if(contextParams.length != 3)
			throw new ApplicationRuntimeException("Incorrect number of service parameters for service " + getName() + ". Expected 2, but got "+ contextParams.length);
        
			String componentPageName = contextParams[1];
			String componentId = contextParams[2];

			IPage componentPage = cycle.getPage(componentPageName);
			IComponent component = componentPage.getNestedComponent(componentId);
        
			if (!(component instanceof IXMLService))
				throw new ApplicationRuntimeException("Incorrect component type: was " + component.getClass() + " but must be " + IXMLService.class, 
						component, null, null);
        
				IXMLService xservice = (IXMLService) component;
        
			// do not squeeze on input
			String[] params = context.getParameters(Tapestry.PARAMETERS_QUERY_PARAMETER_NAME);
			cycle.setServiceParameters(params);
			xservice.trigger(cycle);
        
			// do not squeeze on output either
			Object[] args = cycle.getServiceParameters();
			String strArgs = generateOutputString(args);
			//String strArgs = "";
			output.setContentType("text/xml");
			output.write(strArgs.getBytes("utf-8"));
		}
	
		protected String generateOutputString(Object[] args)
		{
			try {
				DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
				dbf.setValidating(false);
				DocumentBuilder db = dbf.newDocumentBuilder();
				Document doc = db.newDocument();

				Node rootNode = doc.createElement("data");
				doc.appendChild(rootNode);
			
				if (args != null) {
					for (int i = 0; i < args.length; i++) {
						Object value = args[i];
					
						Node spNode = doc.createElement("sp");
						rootNode.appendChild(spNode);
					
						Node valueNode = doc.createTextNode(value.toString());
						spNode.appendChild(valueNode);
					}
				}
			
				TransformerFactory trf = TransformerFactory.newInstance();
				Transformer tr = trf.newTransformer();
				tr.setOutputProperty(OutputKeys.INDENT, "yes");

				DOMSource domSrc = new DOMSource(doc);
				StringWriter writer = new StringWriter();
				StreamResult res = new StreamResult(writer);
				tr.transform(domSrc, res);
				writer.close();
			
				return writer.toString();
			} 
			catch (Exception e) {
				throw new ApplicationRuntimeException("Cannot generate XML", e);
			}
		}
	
    
}
